package dontCare.gwtester.client.puzzlers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

import dontCare.gwtester.client.tool.SourceUrl;
import dontCare.gwtester.client.tool.UnitWidget;

public class Album6 extends UnitWidget{
	private static Album6UiBinder uiBinder = GWT.create(Album6UiBinder.class);
	interface Album6UiBinder extends UiBinder<Widget, Album6> {}
	
	@UiField Label confusing;
	@UiField Label dogCat;
	@UiField Label bark;
	@UiField Label belt;
	@UiField Label notYourType1;
	@UiField Label notYourType3;
	@UiField Label whatsThePoint;
	@UiField Label sumFun;
	@UiField Label nullAndVoid;
	
	public Album6() {
		initWidget(uiBinder.createAndBindUi(this));
		new Confusing(null);	//Puzzler 46
		dogMyCats();
		allIGetIsStatic();
		belt.setText("Elvis wears a size "+Elvis.INSTANCE.beltSize()+" belt.");
		notYourType();
		whatsThePoint.setText(new ColorPoint(4,2,"puple").toString());
		sumFun.setText(""+Cache.getSum());
		nullAndVoid.setText(""+((Null)null).greet());
	}
	
	//Puzzler 46
	class Confusing{
		Confusing(Object o){
			confusing.setText(confusing.getText()+" Object ");
		}
		Confusing(double[] array){
			confusing.setText(confusing.getText()+" double array ");
		}
	}
	//
	
	private void dogMyCats(){
		Dog47 dogs[] = {new Dog47(), new Dog47()};
		for(int i=0; i<dogs.length; i++){
			dogs[i].woof();
		}
		Cat47 cats[] = {new Cat47(), new Cat47(), new Cat47()};
		for(int i=0; i<cats.length; i++){
			cats[i].meow();
		}
		dogCat.setText(Dog47.getCount()+ " woofs and "+Cat47.getCount()+" meows");
	}
	
	private void allIGetIsStatic(){
		Dog48 woofer = new Dog48();
		Dog48 nipper = new Basenji();
		bark.setText(woofer.bark()+nipper.bark());
	}
	
	private void notYourType(){
		//Type1
		String s = null;
		notYourType1.setText(""+(s instanceof String));
		try{
			notYourType3.setText(""+((Album6) new Object()));
		}catch(ClassCastException cce){
			notYourType3.setText(cce.toString());
		}
	}
		
	@Override
	public List<String> getSourceUrl() { 
		ArrayList<String> result = new ArrayList<String>();
		result.add(SourceUrl.genJava(Album6.class));
		result.add(SourceUrl.genUiXml(Album6.class));
		return result;
	}

	@Override
	public HTML getDescription() {
		return new HTML(
			"《Java Puzzlers》 Chapter 6 puzzler 集合。" +
			"<br/>Puzzler 48：為了配合 GWT，將 bark() 從 void 改成回傳 String。"
			+ "<br/>Puzzler 49：Development mode 的結果為「-1930」，詳情參閱 gwt/leakyAbstraction/objectInit" 
			+ "<br/>Puzzler 50：Type2 無法 compile，故跳過。Type3 會產生 ClassCastException，所以多加 try-catch 以能在網頁上顯示結果。"
			+ "<br/>Puzzler 51：Development mode 的結果為「9900」，詳情參閱 gwt/leakyAbstraction/objectInit"
		);
	}

	@Override
	public String getName() {
		return "CH.6 Album";
	}
}

//Puzzler 47
class Counter{
	private static int count;
	public static void increment(){count++;}
	public static int getCount(){return count;}
}

class Dog47 extends Counter{
	public Dog47(){}
	public void woof(){increment();}
}

class Cat47 extends Counter{
	public Cat47(){}
	public void meow(){increment();}
}
//

//Puzzler 48
class Dog48{
	//原本是 public static void bark(){System.out.println("woof");}
	public static String bark(){ return "woof ";}
}

class Basenji extends Dog48{
	//原本是 public static void bark(){};
	public static String bark(){ return "... ";}
}
//

//Puzzler 49
class Elvis{
	public static final Elvis INSTANCE = new Elvis();
	private final int beltSize;
	@SuppressWarnings("deprecation")
	private static final int CURRENT_YEAR = new Date().getYear();	//原本是使用 Calendar.get()
	private Elvis(){
		beltSize = CURRENT_YEAR-1930;
	}
	public int beltSize(){return beltSize;}
}
//

//Puzzler 51
class Point{
	private final int x;
	private final int y;
	private final String name;
	Point(int x, int y){
		this.x=x;
		this.y=y;
		name=makeName();
	}
	
	protected String makeName(){
		return "["+x+","+y+"]";
	}
	
	@Override
	public final String toString(){
		return name;
	}
}

class ColorPoint extends Point{
	private final String color;
	
	ColorPoint(int x, int y, String color){
		super(x,y);
		this.color=color;
	}
	
	@Override
	protected String makeName(){
		return super.makeName()+":"+color;
	}
}
//

//Puzzler 52
class Cache{
	static{ initializeIfNecessary(); }
	
	private static int sum;
	public static int getSum(){
		initializeIfNecessary();
		return sum;
	}

	private static boolean initialized = false;
	private static void initializeIfNecessary() {
		if(!initialized){
			for(int i=0; i<100; i++){
				sum+=i;
			}
			initialized=true;
		}
	}
}
//

//Puzzler 54
class Null {
	//原本是 public static void greet(){System.out.println("Hello world!");}
	public static String greet() {
		return "Hello world!";
	}
}